using System;
using System.Data;
namespace Microsoft.Health.Samples.PatientConnect.TreyResearch.HealthVaultAdapter
{
    /// <summary>
    /// Handles Practice database
    /// </summary>
    public class PracticeDBHandler
    {
        DataSet practiceDataSet;
        DataTable practiceTable;
        DataTable userTable;

        private string practiceXmlFilePath = string.Empty;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="practiceFilePath">Practice Xml file path</param>
        public PracticeDBHandler(string practiceFilePath)
        {
            practiceXmlFilePath = practiceFilePath;
            practiceDataSet = new DataSet("Practices");
            practiceDataSet.Tables.Add(CreatePracticeTable());
            practiceDataSet.Tables.Add(CreateUserTable());

            DataColumn practiceIdColumn = practiceTable.Columns["PracticeId"];
            DataColumn userPracticeIdColumn = userTable.Columns["PracticeId"];

            DataRelation practiceUserRelation = new DataRelation("PracticeUserRelation", practiceIdColumn, userPracticeIdColumn, false);
            practiceDataSet.Relations.Add(practiceUserRelation);

            practiceUserRelation.Nested = true;

            practiceDataSet.ReadXml(practiceXmlFilePath, XmlReadMode.IgnoreSchema);
        }

        /// <summary>
        /// Create Practice Table
        /// </summary>
        /// <returns></returns>
        private DataTable CreatePracticeTable()
        {
            practiceTable = new DataTable("Practice");
            practiceTable.Columns.Add(new DataColumn("PracticeId", typeof(Guid), null, MappingType.Element));
            practiceTable.Columns.Add(new DataColumn("PracticeName", typeof(String), null, MappingType.Element));
            practiceTable.Columns.Add(new DataColumn("childAppId", typeof(Guid), null, MappingType.Element));
            practiceTable.Columns.Add(new DataColumn("DataFolder", typeof(String), null, MappingType.Element));
            return practiceTable;
        }
        
        /// <summary>
        /// Create User Table
        /// </summary>
        /// <returns></returns>
        private DataTable CreateUserTable()
        {
            userTable = new DataTable("Users");
            userTable.Columns.Add(new DataColumn("userid", typeof(Guid), null, MappingType.Element));
            userTable.Columns.Add(new DataColumn("PracticeId", typeof(Guid), null, MappingType.Element));
            userTable.Columns.Add(new DataColumn("username", typeof(String), null, MappingType.Element));
            userTable.Columns.Add(new DataColumn("password", typeof(String), null, MappingType.Element));

            return userTable;
        }

        /// <summary>
        /// Add new practice to practices table
        /// </summary>
        /// <param name="practiceId">PracticeId</param>
        /// <param name="practiceName">Practice name</param>
        /// <param name="childAppId">Child App Id</param>
        /// <param name="dataFolder">Data Folder name</param>
        public void AddPractice(Guid practiceId, string practiceName, Guid childAppId, string dataFolder)
        {
            object[] practiceRow = new object[] {
                    practiceId,
                    practiceName,
                    childAppId,
                    dataFolder
                    };
            practiceTable.Rows.Add(practiceRow);
            Commit();
        }

        /// <summary>
        /// Selects practice with specific condition
        /// </summary>
        /// <param name="condition">condition</param>
        /// <returns>array of data row</returns>
        public DataRow[] SelectPractice(string condition)
        {

            DataRow[] practiceRows = practiceTable.Select(condition);
            return practiceRows;
        }

        /// <summary>
        /// Selects user with specific condition
        /// </summary>
        /// <param name="condition">condition</param>
        /// <returns>array of data row</returns>
        public DataRow[] SelectUsers(string condition)
        {
            DataRow[] userRows = userTable.Select(condition);
            return userRows;
        }

        /// <summary>
        /// Add new user to a practice
        /// </summary>
        /// <param name="userid">user Id</param>
        /// <param name="username">user name</param>
        /// <param name="password">password</param>
        /// <param name="practiceRow">Practice Row for practice Id</param>
        public void AddUsers(Guid userid, string username, string password, DataRow practiceRow)
        {
            object[] userRow = new object[] {
                    userid,
                    practiceRow["PracticeId"],
                    username,
                    password
                    };
            userTable.Rows.Add(userRow);
            Commit();
        }

        /// <summary>
        /// commit the changes to xml file
        /// </summary>
        private void Commit()
        {
            practiceDataSet.WriteXml(practiceXmlFilePath);
        }
    }

}
